package cn.bugstack.infrastructure.redis;

import io.netty.util.Timeout;
import org.redisson.api.*;

import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.concurrent.TimeUnit;

/**
 * @description:
 * @author: wwq
 * @date: 2025/09/01/17:43
 */
public interface IRedisService {

    /**
     * 设置指定key的值
     *
     * @param key   键
     * @param value 值
     * @param <T>
     */
    <T> void setValue(String key, T value);

    /**
     * 设置指定key的值
     *
     * @param key     键
     * @param value   值
     * @param expired 过期时间
     * @param <T>
     */
    <T> void setValue(String key, T value, long expired);

    /**
     * 获取指定key的值
     *
     * @param key
     * @param <T>
     * @return
     */
    <T> T getValue(String key);

    /**
     * 获取队列
     *
     * @param key 键
     * @param <T>
     * @return
     */
    <T> RQueue<T> getQueue(String key);

    /**
     * 加锁队列
     *
     * @param key 键
     * @param <T>
     * @return
     */
    <T> RBlockingQueue<T> getBlockingQueue(String key);

    /**
     * 延迟队列
     *
     * @param rBlockingQueue 加锁队列
     * @param <T>
     * @return
     */
    <T> RDelayedQueue<T> getDelayedQueue(RBlockingQueue<T> rBlockingQueue);

    /**
     * 设置值
     *
     * @param key   key键
     * @param value 值
     */
    void setAtomicLong(String key, long value);

    /**
     * 获取值
     *
     * @param key 键
     * @return
     */
    Long getAtomicLong(String key);

    /**
     * 自增Key的值; 1、2、3、4
     *
     * @param key
     * @return 自增后的值
     */
    long incr(String key);

    /**
     * 自增Key的值；1、2、3、4
     *
     * @param key   键
     * @param delta
     * @return 增后的值
     */
    long incrBy(String key, long delta);

    /**
     * 自减key的值；1、2、3、4
     *
     * @param key
     * @return
     */
    long decr(String key);

    long decrBy(String key, long delta);

    /**
     * 移除指定Key的值
     *
     * @param key
     */
    void remove(String key);

    /**
     * 判断指定key的值是否存在
     *
     * @param key
     * @return
     */
    boolean isExists(String key);

    /**
     * 将指定的值添加到集合中
     *
     * @param key
     * @param value
     */
    void addToSet(String key, String value);

    /**
     * 判断指定的值是否是集合的成员
     *
     * @param key
     * @param value
     * @return
     */
    boolean isSetMember(String key, String value);

    /**
     * 将指定的值添加到列表中
     *
     * @param key
     * @param value
     */
    void addToList(String key, String value);

    /**
     * 获取列表中指定索引的值
     *
     * @param key
     * @param index
     * @return
     */
    String getFromList(String key, int index);

    /**
     * 获取Map
     * @param key
     * @return
     * @param <K>
     * @param <V>
     */
    <K, V> RMap<K, V> getMap(String key);

    /**
     * 将指定的键值对添加到哈希表中
     * @param key
     * @param field
     * @param value
     */
    void addToMap(String key, String field, String value);

    /**
     * 获取哈希表中指定字段的值
     * @param key
     * @param field
     * @return
     */
    String getFromMap(String key, String field);

    <K, V> V getFromMap(String key, K field);

    /**
     * 将指定的值添加到有序集合中
     * @param key
     * @param value
     */
    void addToSortedSet(String key, String value);

    /**
     * 获取Redis 锁
     * @param key
     * @return
     */
    RLock getLock(String key);

    /**
     * 获取Redis锁(公平锁)
     * @param key
     * @return
     */
    RLock getFairLock(String key);

    /**
     * 获取Redis锁(读写锁)
     * @param key
     * @return
     */
    RReadWriteLock getReadWriteLock(String key);

    /**
     * 获取Redis信号量
     * @param key
     * @return
     */
    RSemaphore getSemaphore(String key);

    /**
     * 获取Redis过期信号量
     * 基于Redis的Redisson的分布式信号量(Semaphore) Java对象RSemaphore采用了与java.util.concurrent.
     * Semaphore相似的接口和用法。同时还提供了异步（Async）、反射式（Reactive）和RxJava2标准的接口
     * @param key
     * @return
     */
    RPermitExpirableSemaphore getPermitExpirableSemaphore(String key);

    /**
     * 闭锁
     * @param key
     * @return
     */
    RCountDownLatch getCountDownLatch(String key);

    /**
     * 布隆过滤器
     * @param key
     * @return
     * @param <T>
     */
    <T> RBloomFilter<T> getBloomFilter(String key);

    Boolean setNx(String key);

    Boolean setNx(String key, long expired, TimeUnit timeUnit);

    RBitSet getBitSet(String key);

    default int getIndexFromUserId(String userId) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] hashBytes = md.digest(userId.getBytes(StandardCharsets.UTF_8));
            // 将哈希字节数组转换为正整数
            BigInteger bigInt = new BigInteger(1, hashBytes);
            // 取模以确保索引在合理范围内
            return bigInt.mod(BigInteger.valueOf(Integer.MAX_VALUE)).intValue();
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("MD5 algorithm not found", e);
        }
    }
}
